import axiosInstance from './axios.config';
import type { AxiosRequestConfig, AxiosResponse } from 'axios';

// 定义API响应接口
export interface ApiResponse<T = any> {
  code: number;
  message: string;
  data: T;
}

// 定义请求方法类型
export type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';

// 定义请求配置接口
export interface RequestConfig extends AxiosRequestConfig {
  showLoading?: boolean; // 是否显示加载状态
  showError?: boolean; // 是否显示错误信息
}

/**
 * 通用请求方法
 * @param method 请求方法
 * @param url 请求地址
 * @param data 请求数据
 * @param config 请求配置
 * @returns Promise<ApiResponse<T>>
 */
async function request<T = any>(
  method: RequestMethod,
  url: string,
  data?: any,
  config?: RequestConfig
): Promise<ApiResponse<T>> {
  try {
    const requestConfig: AxiosRequestConfig = {
      method,
      url,
      ...config,
    };

    // 根据请求方法设置数据
    if (method === 'GET' || method === 'DELETE') {
      requestConfig.params = data;
    } else {
      requestConfig.data = data;
    }

    const response = await axiosInstance.request<ApiResponse<T>>(requestConfig);
    return response as any;
  } catch (error) {
    // 统一错误处理
    console.error('请求失败:', error);
    throw error;
  }
}

/**
 * GET请求
 * @param url 请求地址
 * @param params 查询参数
 * @param config 请求配置
 * @returns Promise<ApiResponse<T>>
 */
export function get<T = any>(
  url: string,
  params?: any,
  config?: RequestConfig
): Promise<ApiResponse<T>> {
  return request<T>('GET', url, params, config);
}

/**
 * POST请求
 * @param url 请求地址
 * @param data 请求数据
 * @param config 请求配置
 * @returns Promise<ApiResponse<T>>
 */
export function post<T = any>(
  url: string,
  data?: any,
  config?: RequestConfig
): Promise<ApiResponse<T>> {
  return request<T>('POST', url, data, config);
}

/**
 * PUT请求
 * @param url 请求地址
 * @param data 请求数据
 * @param config 请求配置
 * @returns Promise<ApiResponse<T>>
 */
export function put<T = any>(
  url: string,
  data?: any,
  config?: RequestConfig
): Promise<ApiResponse<T>> {
  return request<T>('PUT', url, data, config);
}

/**
 * DELETE请求
 * @param url 请求地址
 * @param params 查询参数
 * @param config 请求配置
 * @returns Promise<ApiResponse<T>>
 */
export function del<T = any>(
  url: string,
  params?: any,
  config?: RequestConfig
): Promise<ApiResponse<T>> {
  return request<T>('DELETE', url, params, config);
}

/**
 * PATCH请求
 * @param url 请求地址
 * @param data 请求数据
 * @param config 请求配置
 * @returns Promise<ApiResponse<T>>
 */
export function patch<T = any>(
  url: string,
  data?: any,
  config?: RequestConfig
): Promise<ApiResponse<T>> {
  return request<T>('PATCH', url, data, config);
}

/**
 * 上传文件请求
 * @param url 请求地址
 * @param file 要上传的文件对象
 * @param filename 文件名字段名，默认为'file'
 * @param extraData 额外的表单数据
 * @param config 请求配置
 * @returns Promise<ApiResponse<T>>
 */
export function uploadFile<T = any>(
  url: string,
  file: File,
  filename: string = 'file',
  extraData?: Record<string, any>,
  config?: RequestConfig
): Promise<ApiResponse<T>> {
  const formData = new FormData();

  // 添加文件
  formData.append(filename, file);

  // 添加额外数据
  if (extraData) {
    Object.keys(extraData).forEach((key) => {
      formData.append(key, extraData[key]);
    });
  }

  // 设置请求头，确保不设置Content-Type，让浏览器自动处理
  const uploadConfig: RequestConfig = {
    ...config,
    headers: {
      ...config?.headers,
      'Content-Type': 'multipart/form-data',
    },
  };

  return request<T>('POST', url, formData, uploadConfig);
}

// 导出axios实例，供特殊需求使用
export { axiosInstance };

// 默认导出请求方法
export default {
  get,
  post,
  put,
  delete: del,
  patch,
  uploadFile,
};
